package com.onmicro.snc_ble.core.bluetooth;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.ParcelUuid;

import com.onmicro.snc_ble.app.App;
import com.onmicro.snc_ble.dialog.SweetAlertDialog;

import static java.lang.System.arraycopy;


/**
 * @author peng
 */
@TargetApi(21)
public class BeaconTransmitter {
    private Context context = null;

    private AdvertiseCallback mAdvertiseCallback;

    private AdvertiseSettings mAdvertiseSettings;

    private AdvertiseCallback mAdvertisingClientCallback;

    private BluetoothAdapter mBluetoothAdapter;

    private BluetoothLeAdvertiser mBluetoothLeAdvertiser;

    private BluetoothManager mBluetoothManager;

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context param1Context, Intent param1Intent) {
            if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(param1Intent.getAction())) {
                int i = param1Intent.getIntExtra("android.bluetooth.adapter.extra.STATE", -2147483648);
                if (i != Integer.MIN_VALUE) {
                    switch (i) {
                        case BluetoothAdapter.STATE_OFF:
                            System.out.println("Bluetooth STATE_OFF");
                            alertDialog();
                            break;
                        case BluetoothAdapter.STATE_TURNING_ON:
                            System.out.println("Bluetooth STATE_TURNING_ON");
                            break;
                        case BluetoothAdapter.STATE_ON:
                            System.out.println("Bluetooth STATE_ON");
                            bluetoothLeAdvertiser();
                            break;
                        case BluetoothAdapter.STATE_TURNING_OFF:
                            System.out.println("Bluetooth STATE_TURNING_OFF");
                            break;
                        default:
                            break;
                    }
                }
                System.out.println("Bluetooth ERROR");
            }
        }
    };

    public BeaconTransmitter(Context paramContext) {
        this.context = paramContext;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            this.mBluetoothManager = (BluetoothManager) paramContext.getSystemService(Context.BLUETOOTH_SERVICE);
            if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
                alertDialog();
                System.out.println("Bluetooth STATE_ON");
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mBluetoothManager != null) {
                mBluetoothAdapter = mBluetoothManager.getAdapter();
                bluetoothLeAdvertiser();
            }
            mAdvertiseSettings = (new AdvertiseSettings.Builder())
                    .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
                    .setConnectable(true)
                    .setTimeout(0)
                    .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
                    .build();
        }
        start();
    }

    private void alertDialog() {
        new SweetAlertDialog(App.getContext())
                .setTitleText("提示")
                .setContentText("打开蓝牙来允许\"昂瑞微灯控\"连接到配件")
                .setCancelText("取消")
                .setConfirmText("确定").
                setConfirmClickListener(param1SweetAlertDialog ->
                        BeaconTransmitter.this.openSetting("")).show();
    }

    private void bluetoothLeAdvertiser() {
        if (mBluetoothAdapter != null && mBluetoothLeAdvertiser == null) {
            mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
        }
    }

    private AdvertiseData buildData(char[] paramArrayOfChar) {
        AdvertiseData.Builder builder = new AdvertiseData.Builder();
        builder.setIncludeDeviceName(false);
        StringBuffer stringBuffer = new StringBuffer();
        for (byte b = 0; b < 16; b++) {
            stringBuffer.append(String.format("%02X", (byte) paramArrayOfChar[b]));
            if (b == 3 || b == 5 || b == 7 || b == 9)
                stringBuffer.append("-");
        }
        builder.addServiceUuid(ParcelUuid.fromString(stringBuffer.toString()));
        return builder.build();
    }

    private AdvertiseCallback getAdvertiseCallback() {
        if (mAdvertiseCallback == null)
            mAdvertiseCallback = new AdvertiseCallback() {
                @Override
                public void onStartFailure(int param1Int) {
                    if (mAdvertisingClientCallback != null)
                        mAdvertisingClientCallback.onStartFailure(param1Int);
                }

                @Override
                public void onStartSuccess(AdvertiseSettings param1AdvertiseSettings) {
                    if (mAdvertisingClientCallback != null)
                        mAdvertisingClientCallback.onStartSuccess(param1AdvertiseSettings);
                }
            };
        return mAdvertiseCallback;
    }

    private void openSetting(String paramString) {
        Intent intent = new Intent();
        intent.setAction("android.settings.BLUETOOTH_SETTINGS");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.bluetooth.adapter.action.STATE_CHANGED");
        intentFilter.addAction("android.bluetooth.adapter.action.DISCOVERY_STARTED");
        intentFilter.addAction("android.bluetooth.adapter.action.DISCOVERY_FINISHED");
        context.registerReceiver(receiver, intentFilter);
    }

    public void startAdvertising(char[] paramArrayOfChar) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                stopAdvertising();
                mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, buildData(paramArrayOfChar), getAdvertiseCallback());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 2.4G advertising
     *
     * @param data
     */
    public void startAdvertising(byte[] data) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                stopAdvertising();
                mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, buildData(data), getAdvertiseCallback());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 2.4G build data
     *
     * @param data
     * @return
     */
    private AdvertiseData buildData(byte[] data) {

        byte[] manufactureID = {(byte) 0X01, (byte) 0XBF};
        // reverse bytes of manufactureId
        int manufactureId = (int) manufactureID[0] & 0x00FF;
        manufactureId <<= 8;
        manufactureId += (int) manufactureID[1] & 0x00FF;

        return new AdvertiseData.Builder()
                .setIncludeDeviceName(false)
                .setIncludeTxPowerLevel(false)
                .addManufacturerData(manufactureId, data)
                .build();

    }


    public void startAdvertising(char[] paramArrayOfChar, AdvertiseCallback paramAdvertiseCallback) {
        mAdvertisingClientCallback = paramAdvertiseCallback;
        startAdvertising(paramArrayOfChar);
    }

    public void stopAdvertising() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mAdvertisingClientCallback = null;
            try {
                mBluetoothLeAdvertiser.stopAdvertising(getAdvertiseCallback());
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
    }
}
